﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Skyhook.Core;
using Skyhook.Resources;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Skyhook.Sprites
{
	internal class SpriteObject : IVisualObject
	{
        Sprite[] Sprites = null;
        int[] Layers = null;
        IScreenPosition ScreenPosition = null;

        ISpriteRenderer SpriteRenderer = null;
        
        List<Sprite>[] VisibleSprites = null;
        
        int VisibleSpritesCount = 0;

        public SpriteObject(ImageCollection image, int[] entitygroups, SpriteLayersLayout layerslayout, ISpriteRenderer spriterenderer = null)
        {
            int spritescount = entitygroups.Length / 3;
            Sprites = new Sprite[spritescount];
            Layers = new int[spritescount];
            VisibleSprites = new List<Sprite>[SpriteLayers.Maximum + 1];

            for (int i = 0; i < spritescount; i++)
            {
                Sprites[i] = new Sprite(image, entitygroups[i * 3 + 1], entitygroups[i * 3 + 2]);
                Layers[i] = layerslayout[entitygroups[i * 3]];
            }
            
            for(int i = 0; i <= SpriteLayers.Maximum; i++)
            {
                VisibleSprites[i] = new List<Sprite>();
            }

            if (spriterenderer == null)
            {
                SpriteRenderer = new SpriteFullRenderer();
            }
            else
            {
                SpriteRenderer = spriterenderer;
            }
        }

        public virtual void Render(SpriteBatch batch,int layer, Color color = default(Color), float depth = 0.0f)
        {
            if (depth == 0.0f)
            {
                depth = ScreenPosition.Depth;
            }
            if (color == default(Color))
            {
                color = Color.White;
            }
            for (int i = 0; i < VisibleSprites[layer].Count; i++)
            {
                SpriteRenderer.Render(batch, VisibleSprites[layer][i], ScreenPosition.ScreenPosition,color, depth);
            }
        }

        public virtual int GroupsCount
        {
            get
            {
                return Sprites.Length;
            }
        }

        public virtual void SetGroupsCurrentEntity(int entitynum, int group)
        {
            Sprites[group].CurrentFrame = entitynum;
        }

        public virtual void SetGroupsCurrentEntity(int entitynum, int group1, int group2)
        {
            Sprites[group1].CurrentFrame = entitynum;
            Sprites[group2].CurrentFrame = entitynum;
        }

        public virtual void SetGroupsCurrentEntity(int entitynum, int group1, int group2, int group3)
        {
            Sprites[group1].CurrentFrame = entitynum;
            Sprites[group2].CurrentFrame = entitynum;
            Sprites[group3].CurrentFrame = entitynum;
        }

        public virtual void SetGroupsCurrentEntity(int entitynum, int group1, int group2, int group3, int group4)
        {
            Sprites[group1].CurrentFrame = entitynum;
            Sprites[group2].CurrentFrame = entitynum;
            Sprites[group3].CurrentFrame = entitynum;
            Sprites[group4].CurrentFrame = entitynum;
        }

        public virtual void ShowGroups(params int[] groupnums)
        {
            for (int i = 0; i <= SpriteLayers.Maximum; i++)
            {
                VisibleSprites[i].Clear();
            }
            VisibleSpritesCount = 0;
            for (int i = 0; i < groupnums.Length; i++)
            {
                VisibleSprites[Layers[groupnums[i]]].Add(Sprites[groupnums[i]]);
                VisibleSpritesCount++;
            }
        }

        protected void CloneSprites()
        {
            Sprite[] newSprites = new Sprite[Sprites.Length];
            int[] newLayers = new int[Sprites.Length];
            for (int i = 0; i < Sprites.Length; i++)
            {
                newSprites[i] = Sprites[i].Clone();
                newLayers[i] = Layers[i];
            }
            Sprites = newSprites;
            Layers = newLayers;

            VisibleSprites = new List<Sprite>[SpriteLayers.Maximum + 1];

            for (int i = 0; i <= SpriteLayers.Maximum; i++)
            {
                VisibleSprites[i] = new List<Sprite>();
            }
        }

        public virtual SpriteObject Clone()
        {
            SpriteObject result = (SpriteObject)this.MemberwiseClone();
            result.CloneSprites();
            return result;
        }

        public virtual int GetNumberEntitiesInGroup(int groupnum)
        {
            return Sprites[groupnum].FramesCount;
        }

        public virtual Sprite this[int index]
        {
            get
            {
                return Sprites[index];
            }
        }

        public virtual void SetScreenPosition(IScreenPosition screenposition)
        {
            ScreenPosition = screenposition;
        }

        public virtual void SetScreenShift(Vector2 shift)
        {
            ScreenPosition.Shift = shift;
        }
	}
}
